﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TY.GateWay
{
    using System;
    using System.IO;
    using System.Net;
    using System.Text;
    using DotNetty.Buffers;
    using DotNetty.Transport.Channels;
    using DotNetty.Transport.Channels.Groups;
    using Google.Protobuf;
    using MO.Protocol;
    using ProtoBuf;

    public class ServerHandler : SimpleChannelInboundHandler<BasicMessage>
    {
        static volatile IChannelGroup group;

        public override void ChannelActive(IChannelHandlerContext contex)
        {
            IChannelGroup g = group;
            if (g == null)
            {
                lock (this)
                {
                    if (group == null)
                    {
                        g = group = new DefaultChannelGroup(contex.Executor);
                    }
                }
            }

            //contex.WriteAndFlushAsync(string.Format("Welcome to {0} secure chat server!\n", Dns.GetHostName()));
            g.Add(contex.Channel);
            Console.WriteLine("欢迎：" + Dns.GetHostName());
        }

        class EveryOneBut : IChannelMatcher
        {
            readonly IChannelId id;

            public EveryOneBut(IChannelId id)
            {
                this.id = id;
            }

            public bool Matches(IChannel channel) => channel.Id != this.id;
        }

        protected override void ChannelRead0(IChannelHandlerContext context, BasicMessage message)
        //public override async void ChannelRead(IChannelHandlerContext context, object message)
        {

            // message.Req = null;
            message.Resp = new BasicResp();
            switch (message.ActionId)
            {
                case ActionCMD.Login:
                    message.Resp.Header= new Header { LoginId=1, LoginType= Header.Types.LoginType.Wx, LoginUser="abc", NickName="efg", Token= context.Channel.Id.AsLongText() }
                    break;
                case ActionCMD.Matched:
                    message.Resp.MatchTeam = new MatchTeam { Status = MatchTeam.Types.MatchTeamStatus.Sucess, TeamId = group.Name };
                    break;
                case ActionCMD.EntryGame:
                    message.Resp.EntryGame = new EntryScene
                    {
                        Players = new Google.Protobuf.Collections.RepeatedField<Header> { },
                        Items = new Google.Protobuf.Collections.RepeatedField<Item> { },
                        Resouces = new Google.Protobuf.Collections.RepeatedField<Resource> { }
                    };
                    break;
                case ActionCMD.GameEnd:
                    break;
                default:
                    break;
            }

            Console.WriteLine(message.ActionId);
            Console.WriteLine(message.Code);
            switch (message.Status)
            {
                case messageStatus.OnlyMe:
                    context.WriteAndFlushAsync(message);
                    break;
                case messageStatus.OnlyTeam:
                    group.WriteAndFlushAsync(message, new EveryOneBut(context.Channel.Id));
                    break;
                case messageStatus.AllTeam:
                    group.WriteAndFlushAsync(message, new EveryOneBut(context.Channel.Id));
                    context.WriteAndFlushAsync(message);
                    break;
                default:
                    break;
            }

          
            //if (message is C2S100007 c2)
            //{

            //}
            //else if (message is C2S100009 c9)
            //{

            //}
            //using (var ms = new MemoryStream())
            //{
            //    if (message is C2S100007 c2)
            //    {

            //    }
            //    var c = message;
            //    byte[] bytes = new byte[1024];
            //    message.WriteBytes(bytes);
            //    ms.Write(bytes, 0, bytes.Length);
            //   var p=  Serializer.Deserialize<C2S100007>(ms);
            //   var e=  Serializer.Deserialize<C2S100009>(ms);
            //}

            //send message to all but this one

            //  string msg = Encoding.UTF8.GetString(message.Array);

            //group.WriteAndFlushAsync(message, new EveryOneBut(context.Channel.Id));
            //context.WriteAndFlushAsync(message);

            //if (string.Equals("bye", msg, StringComparison.OrdinalIgnoreCase))
            //{
            //    contex.CloseAsync();
            //}
        }
        public override Task WriteAsync(IChannelHandlerContext context, object message)
        {
            return base.WriteAsync(context, message);
        }
        public override void ChannelReadComplete(IChannelHandlerContext ctx) => ctx.Flush();

        public override void ExceptionCaught(IChannelHandlerContext ctx, Exception e)
        {
            Console.WriteLine("{0}", e.StackTrace);
            ctx.CloseAsync();
        }

        public override bool IsSharable => true;
    }
}
